package com.example.agreement.io;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

//非阻塞IO
public class NIO {
    public void serve(int port) throws IOException{
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.configureBlocking(false);
        ServerSocket ss = serverChannel.socket();
        InetSocketAddress address = new InetSocketAddress(port);
        ss.bind(address);                                               //1
        Selector selector = Selector.open();                            //2
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);       //3
        final ByteBuffer msg = ByteBuffer.wrap("Hi!\r\n".getBytes());
        for (;;){
            try{
                selector.select();                                       //4
            }catch (IOException ex){
                ex.printStackTrace();
                break;
            }
            Set<SelectionKey> readyKeys = selector.selectedKeys();        //5
            Iterator<SelectionKey> iterator = readyKeys.iterator();
            while (iterator.hasNext()){
                SelectionKey key = iterator.next();
                iterator.remove();
                try {
                    if (key.isAcceptable()){                               //6
                        ServerSocketChannel server =
                                (ServerSocketChannel)key.channel();
                        SocketChannel client = server.accept();
                        client.configureBlocking(false);
                        client.register(selector,SelectionKey.OP_WRITE |
                                SelectionKey.OP_READ,msg.duplicate());         //7
                        System.out.println("Accepted connection from 接收成功" + client);
                    }
                    if (key.isWritable()){                                    //8
                        SocketChannel client =
                                (SocketChannel) key.channel();
                        ByteBuffer buffer =
                        (ByteBuffer) key.attachment();
                        while (buffer.hasRemaining()){
                            if (client.write(buffer) == 0){                   //9
                                break;
                            }
                        }
                        client.close();                                        //10
                    }
                }catch (IOException ex){
                    key.channel();
                    try {
                        key.channel().close();
                    }catch (IOException cex){
                        // 在关闭时忽略
                    }
                }
            }
        }
    }
}
